package com.naiterui.common.repository.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import javax.persistence.EntityManager;

import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.common.repository.exception.DataAccessOpException;
import com.naiterui.common.repository.exception.DataAccessSafeException;

/**
 * 基于SimpleJpaRepository，用于扩展spring-data-jpa相关Repository接口的默认实现，
 * 在配置repository时要将改类作为base-class进行制定，
 * 该类同时也是BaseJpaRepository的实现，扩展的相关行为参见父接口
 *
 * @author zhouyanxin
 * @since 1.0.0
 */
public final class BaseJpaRespositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseJpaRepository<T, ID> {

    /**
     * Entity Manager
     */
    private final EntityManager entityManager;
    private final JpaEntityInformation<T, ?> entityInformation;

    /**
     * 构造函数
     */
    public BaseJpaRespositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
        this.entityInformation = entityInformation;
    }

    /**
     * 根据ID获取实体
     *
     * @since 1.0.0
     */
    @Override
    public T get(ID id) {
        Optional<T> option = this.findById(id);
        return option.orElse(null);
    }

    /**
     * 批量保存实体对象
     * 其行为的变化在于不处理对象的更新
     *
     * @since 1.0.0
     */
    @Override
    @Transactional
    public <S extends T> List<S> save(Iterable<S> entities) {
        return super.saveAll(entities);
    }

    /**
     * 更新实体
     *
     * @since 1.0.0
     */
    @Override
    @Transactional
    public <S extends T> S update(S s) {
        return super.save(s);
    }

    /**
     * 批量更新实体对象
     */
    @Transactional
    @Override
    public <S extends T> List<S> update(Iterable<S> entities) {
        return super.saveAll(entities);
    }

    /**
     * 删除对象
     */
    @Override
    @Transactional
    public <S extends T> void remove(S s) {
        super.delete(s);
    }

    /**
     * 批量删除
     */
    @Override
    @Transactional
    public void remove(List<T> entities) {
        super.deleteInBatch(entities);
    }

    /**
     * 根据ID删除对象
     */
    @Override
    @Transactional
    public void removeById(ID id) {
        super.deleteById(id);
    }

    /**
     * 禁用该方法
     */
    @Override
    @Transactional
    public void deleteAll() {
        throw new DataAccessSafeException("not support operation, This operation is risky !");
    }

    /**
     * 禁用该方法
     */
    @Override
    @Transactional
    public void deleteAllInBatch() {
        throw new DataAccessSafeException("not support operation, This operation is risky !");
    }

}
